//合法的数字格式 ' ' +/- number . number e/E +/- number ' '
enum {
    type_sign,
    type_num,
    type_dot,
    type_e_E,
    type_illegal
};

enum {
    state_start,
    state_before_e,
    state_after_e
};

int get_char_type(char ch)
{
    if (ch == '+' || ch == '-') return type_sign;
    else if (ch >= '0' && ch <= '9') return type_num;
    else if (ch == '.') return type_dot;
    else if (ch == 'e' || ch == 'E') return type_e_E;
    else return type_illegal;
}
// dot只能出现在e前，且只能出现1次；
// sign可以出现在e两边

bool isNumber(char* s){
    int type, st, len = strlen(s);
    int dot_appear = 0, sign_appear = 0, num_appear = 0; 
    int i = 0, j = len - 1;
    if (s == NULL || len == 0) return false;
    
    //删除首尾空格
    while(s[i] == ' ') i++;
    //空字符串
    if (i > j) return false;
    while(s[j] == ' ') j--;
    

    st = state_start;
    while (i <= j) {
        type = get_char_type(s[i]);
        switch (st) {
            case state_start:   // +/- number .
                if (type == type_sign) st = state_before_e; 
                else if (type == type_num) {
                    num_appear++;
                    st = state_before_e; 
                }
                else if (type == type_dot) {    //下一个状态可以出现'.', 需记数
                    dot_appear++;
                    st = state_before_e; 
                }
                else 
                    return false;
                break;

            case state_before_e:   //可能没有指数e
            // number . e/E     —— yes; dot_appear记数
            // +/-  illegal     —— no
                if (type == type_num) {
                        num_appear++;
                        st = state_before_e; 
                    }
                else if (type == type_dot) {    
                    dot_appear++;
                    if (dot_appear > 1) //出现多个'.' 
                        return false;
                    st = state_before_e; 
                }
                else if (i != j && type == type_e_E) {  //e,E不能是末尾
                    st = state_after_e; 
                }
                else 
                    return false;
                break;

            case state_after_e:
                // +/- number ' '         —— yes; sign_appear记数 
                // . e/E illegal          —— no
                if (i != j && type == type_sign) { //末尾不能为‘+’
                    sign_appear++;
                    if (sign_appear > 1) return false;
                    st = state_after_e;
                }
                else if (type == type_num) {
                    st = state_after_e;
                }
                else   
                    return false;
                break;

            default:    // error state
                return false;
                break;
        }
        i++;
    }
    if (!num_appear) return false;
    return true;
}